package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.dto.ShoppingCartDTO;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.LoginFailedException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.UserMapper;
import com.sky.properties.WeChatProperties;
import com.sky.service.Usersevice;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.UserLoginVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static com.sky.constant.MessageConstant.*;
import static com.sky.entity.Orders.PENDING_PAYMENT;

@Slf4j
@Service
@Transactional
public class Userservicelml  implements Usersevice {

    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private WeChatPayUtil weChatPayUtil;

    @Override
    public User wxlogin(UserLoginDTO userLoginDTO) {
        //调用doget并带四个参数请求https://api.weixin.qq.com/sns/jscode2session地址获取String类型的openID
        HashMap<String, String> map = new HashMap<>();
        map.put("appid",weChatProperties.getAppid());
        map.put("secret",weChatProperties.getSecret());
        map.put("js_code",userLoginDTO.getCode());
        map.put("grant_type","authorization_code");
        //微信的 jscode2session 接口返回的是JSON格式的数据
        String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", map);
        // 需要 JSONObject 对象接收
        JSONObject jsonObject = JSON.parseObject(s);
        //提取具体的字段值
        String openid = jsonObject.getString("openid");
        if(openid!=null)
        {
            //如果openid不为空
            //根据openid查询用户
            User user = userMapper.selectuserbyopenid(openid);
            if(user==null)
            {
                //如果用户为空，表示用户第一次登录，则直接注册用户
                //构建用户
                User user1 = User.builder()
                        .openid(openid)
                        .createTime(LocalDateTime.now())
                        .build();
                //调用insert方法插入用户数据
                int count = userMapper.insertuser(user1);
                return user1;
            }
            else {
                return user;
            }


        }
        else {
            //判断openid是否为空，如果为空表示登录失败，抛出业务异常
            throw new LoginFailedException(LOGIN_FAILED );
        }





        //返回用户数据
    }

    @Override
    public int addshopcart(ShoppingCart cart) {
        log.info("用户id:{}",BaseContext.getCurrentId());
        cart.setUserId(BaseContext.getCurrentId());
        //根据条件查询购物车列表 判断是否有相同的菜品或套餐
        ShoppingCart shoppingCart= userMapper.selectbyconditions(cart);
        log.info("shoppingCart is {}",shoppingCart);
        if(shoppingCart!=null)
        {
            //相同的菜品 数量加1即可
            int updatenum = userMapper.updatenum(shoppingCart, shoppingCart.getNumber() + 1);
            return updatenum;
        }
        else {
            //购物车没有的菜品或套餐，插入到购物车
            //判断是菜品还是套餐
            if(cart.getDishId()!=null)
            {
                //如果是菜品的话
                //插入菜品
                Dish dish = dishMapper.selectbyid(cart.getDishId());
                cart.setImage(dish.getImage());
                cart.setAmount(dish.getPrice());
                cart.setName(dish.getName());
                cart.setNumber(1);
                cart.setCreateTime(LocalDateTime.now());
                int dishcount = userMapper.insertaddshopcart(cart);
                return dishcount;
            }
            else {
                //如果是套餐的话
                //插入套餐
                Setmeal setmeal= setmealMapper.getbyid(cart.getSetmealId());
                cart.setName(setmeal.getName());
                cart.setImage(setmeal.getImage());
                cart.setAmount(setmeal.getPrice());
                cart.setNumber(1);
                cart.setCreateTime(LocalDateTime.now());
                int setmealcount = userMapper.insertaddshopcart(cart);
                return setmealcount;
            }
        }
    }

    @Override
    public List<ShoppingCart> selectallshopcart(Long id) {
        List<ShoppingCart> shopcarts = userMapper.selectallshopcart(id);
        return shopcarts;
    }

    @Override
    public void deleteall(Long id) {
        userMapper.deleteall(id);
    }

    @Override
    public OrderSubmitVO ordersubmit(OrdersSubmitDTO ordersSubmitDTO) {
        //非空判断（地址非空，购物车非空
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if(addressBook==null)
        {
            throw new AddressBookBusinessException(ADDRESS_BOOK_IS_NULL);
        }
        List<ShoppingCart> shoppingCarts = userMapper.selectallshopcart(BaseContext.getCurrentId());
        if(shoppingCarts==null &&shoppingCarts.size()>0)
        {
            throw new ShoppingCartBusinessException(SHOPPING_CART_IS_NULL);
        }
            //构建订单数据
            String s = UUID.randomUUID().toString().replaceAll("-", "");
            Orders order = Orders.builder()
                    .number(s)
                    .status(PENDING_PAYMENT)
                    .userId(BaseContext.getCurrentId())
                    .addressBookId(ordersSubmitDTO.getAddressBookId())
                    .orderTime(LocalDateTime.now())
                    .payMethod(ordersSubmitDTO.getPayMethod())
                    .payStatus(Orders.UN_PAID) // 设置默认未支付状态
                    .amount(ordersSubmitDTO.getAmount())
                    .remark(ordersSubmitDTO.getRemark())
                    .phone(addressBook.getPhone())
                    .address(addressBook.getDetail())
                    .consignee(addressBook.getConsignee())
                    .estimatedDeliveryTime(ordersSubmitDTO.getEstimatedDeliveryTime())
                    .deliveryStatus(ordersSubmitDTO.getDeliveryStatus())
                    .packAmount(ordersSubmitDTO.getPackAmount())
                    .tablewareNumber(ordersSubmitDTO.getTablewareNumber())
                    .tablewareStatus(ordersSubmitDTO.getTablewareStatus())
                    .build();
            //插入订单数据
        try {
            int ordercount = userMapper.insertorder(order);
            log.info("ordercount is {}", ordercount);
        } catch (Exception e) {
            log.error("插入订单失败", e);
            e.printStackTrace();
            throw e;
        }
        log.info("order id is{}",order.getId());
            //插入多条订单明细数据 //一个订单可以对应多个订单明细
            for (ShoppingCart shoppingCart : shoppingCarts) {
                Long dishId = shoppingCart.getDishId();
                if (dishId == null) {
                    //如果是套餐
                    OrderDetail setmeal = OrderDetail.builder()
                            .name(shoppingCart.getName())
                            .image(shoppingCart.getImage())
                            .orderId(order.getId())
                            .setmealId(shoppingCart.getSetmealId())
                            .number(shoppingCart.getNumber())
                            .amount(shoppingCart.getAmount())
                            .build();
                    //插入订单详细
                    try {
                    int setmealcount = userMapper.inserorderdetail(setmeal);
                    log.info("setmealcount is {}", setmealcount);
                    }catch (Exception e)
                    {
                        e.printStackTrace();
                        throw e;
                    }
                } else {
                    OrderDetail dish = OrderDetail.builder()
                            .name(shoppingCart.getName())
                            .image(shoppingCart.getImage())
                            .orderId(order.getId())
                            .dishId(shoppingCart.getDishId())
                            .dishFlavor(shoppingCart.getDishFlavor())
                            .number(shoppingCart.getNumber())
                            .amount(shoppingCart.getAmount())
                            .build();
                    try {
                        int dishcount = userMapper.inserorderdetail(dish);
                        log.info("dishcount is {}", dishcount);
                    }catch (Exception e)
                    {
                        e.printStackTrace();
                        throw e;
                    }
                }

            }
            //清空购物车数据
            userMapper.deleteall(BaseContext.getCurrentId());
            //返回OrderSubmitVO
            OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                    .id(order.getId())
                    .orderNumber(order.getNumber())
                    .orderAmount(order.getAmount())
                    .orderTime(order.getOrderTime())
                    .build();
            log.info("orderSubmitVO is {}", orderSubmitVO);
        return orderSubmitVO;
    }

}
